Skip to content

Expose more Sqlalchemy settings, part 1#16742

Merged
zzstoatzz merged 14 commits intomainfrom
sqlalchemy-settings
Jan 17, 2025
Merged

Expose more Sqlalchemy settings, part 1#16742
zzstoatzz merged 14 commits intomainfrom
sqlalchemy-settings

Conversation

@cicdw
Copy link
Member

@cicdw cicdw commented Jan 15, 2025

This PR exposes additional SQLAlchemy configuration settings through Prefect settings to enable improved testing and optimization of database setups.

Note that this PR also introduces a change to our default SQLAlchemy configuration: specifically, it adds a new default of pool_recycle=3600 where we used to not use pool recycling at all.

If accepted, part 2 would be to expose settings that configure the connect_args specifically (which include application name, statement caching, etc.).


nate

  • makes build_settings_config public but preserves a private copy to avoid breaking integrations
  • fixes backwards compat for setting sqlalchemy_* settings in prefect.toml by removing the fields from the parent ServerDatabaseSettings and allow get/set through the parent (with a DeprecationWarning). the only way users should encounter this is by setting these settings via prefect.toml, the env vars should always go to the right place
  • also fixed typing in many test signatures

if self.timeout is not None:
kwargs["connect_args"] = dict(timeout=self.timeout)

if self.sqlalchemy_pool_size is not None:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added these in #16690 so this won't affect any released behavior.

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 15, 2025

CodSpeed Performance Report

Merging #16742 will not alter performance

Comparing sqlalchemy-settings (59b7e1c) with main (97708c2)

Summary

✅ 2 untouched benchmarks

Copy link
Collaborator

@zzstoatzz zzstoatzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Copy link
Collaborator

@zzstoatzz zzstoatzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

going to add some changes to avoid breaking the dotted key path here

Copy link
Collaborator

@zzstoatzz zzstoatzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to unblock since i had requested changes

Details

image

Comment on lines +204 to +244
def __getattribute__(self, name: str) -> Any:
if name in ["sqlalchemy_pool_size", "sqlalchemy_max_overflow"]:
warnings.warn(
f"Setting {name} has been moved to the `sqlalchemy` settings group.",
DeprecationWarning,
)
field_name = name.replace("sqlalchemy_", "")
return getattr(super().__getattribute__("sqlalchemy"), field_name)
return super().__getattribute__(name)

# validators

@model_validator(mode="before")
@classmethod
def set_deprecated_sqlalchemy_settings_on_child_model_and_warn(
cls, values: dict[str, Any]
) -> dict[str, Any]:
"""
Set deprecated settings on the child model.
"""
# Initialize sqlalchemy settings if not present
if "sqlalchemy" not in values:
values["sqlalchemy"] = SQLAlchemySettings()

if "sqlalchemy_pool_size" in values:
warnings.warn(
"`sqlalchemy_pool_size` has been moved to the `sqlalchemy` settings group as `pool_size`.",
DeprecationWarning,
)
if "pool_size" not in values["sqlalchemy"].model_fields_set:
values["sqlalchemy"].pool_size = values["sqlalchemy_pool_size"]

if "sqlalchemy_max_overflow" in values:
warnings.warn(
"`sqlalchemy_max_overflow` has been moved to the `sqlalchemy` settings group as `max_overflow`.",
DeprecationWarning,
)
if "max_overflow" not in values["sqlalchemy"].model_fields_set:
values["sqlalchemy"].max_overflow = values["sqlalchemy_max_overflow"]

return values
Copy link
Collaborator

@zzstoatzz zzstoatzz Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first part handles access to the values via the parent, second handles setting the values on the child if passed to the parent. env vars should go straight to the child via validation_alias on the child model's fields

Copy link
Member

@desertaxle desertaxle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I left a comment for one more test case that I think would be useful, but that's non-blocking.

assert settings_with_new_keys.server.database.sqlalchemy.pool_size == 42
assert settings_with_new_keys.server.database.sqlalchemy.max_overflow == 37

def test_sqlalchemy_settings_migration_via_env_var(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of abundance of caution, it might be a good idea to add a test for the TOML method of setting also.

@zzstoatzz zzstoatzz merged commit ea87722 into main Jan 17, 2025
54 checks passed
@zzstoatzz zzstoatzz deleted the sqlalchemy-settings branch January 17, 2025 02:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs enhancement An improvement of an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants